home *** CD-ROM | disk | FTP | other *** search
/ Loadstar 128 #10 / q10.d81 / t.gbasic demo < prev    next >
Encoding:
Text File  |  1990-01-01  |  17.1 KB  |  356 lines

  1.                         G B A S I C   1 2 8   V 1 .  0
  2.  
  3.                                 By Jon Mattson
  4.  
  5.  
  6. When the C-128 first appeared on the scene with its greatly improved BASIC
  7. 7.0, general consensus was that it would be a boon to anyone who wanted to
  8. program fast games but didn't have the knowledge to work with machine
  9. language.  The interrupt-based movement commands, in particular, seemed
  10. ideal for this.  For me, it became a challenge to see how few lines I could
  11. use in the main loop of a game.  GANGSTER, on LOADSTAR 128 #4, was one of
  12. the results of this experiment.  A new Renaissance in game programming
  13. seemed inevitable.
  14.  
  15. Of course, as with so many things in life, BASIC 7.0 failed to live up to
  16. expectations.  True, MOVSPR allows interrupt-driven movement, independent of
  17. the main program, but the coding required to keep the little beggars fenced
  18. in where you want them almost entirely negates the savings in time and
  19. space.  True, SPRSAV allows relatively simple animation, but it is not very
  20. fast (compared to ML) and must still be monitored from BASIC, since it is
  21. not serviced by the interrupt.  True, BUMP(1) is easier to remember than
  22. PEEK(53278), but that is the only real difference: it still doesn't tell you
  23. which sprite hit which in a mass collision (ditto for COLLISION).  True, JOY
  24. returns a more human-oriented result, but the computer still doesn't do
  25. anything with it.
  26.  
  27. Clearly, what BASIC 7.0 needs is some sort of subset of commands designed to
  28. deal with all of these shortcomings.  That is exactly what you now have at
  29. your fingertips with GBASIC.
  30.  
  31. GBASIC actually began as an attempt to create a sort of "sprite shell" to
  32. keep tabs on things in the background of a program.  Even in its initial
  33. incarnation, it dealt with all of the problems noted above.  However, when I
  34. noticed that I still had a little memory to play around with in the
  35. 4864-7168 range, I thought I might as well add a few more commands of use to
  36. game programmers.  The end result is a collection of 14 commands and 2
  37. functions, all of which operate harmoniously with your usual collection of
  38. BASIC 7.0 tools.
  39.  
  40. Using GBASIC is simple.  Just BLOAD it into memory and SYS 4864, either in
  41. direct mode or early on in your program.  If you are in direct mode, a
  42. message will inform you that it is installed.  This message will not appear
  43. from within a program, however, since it might ruin your screen
  44. presentation.  Generally, a simple BLOAD will suffice, but, if you have been
  45. playing around with BANKs and the like, you might want to use the full
  46. syntax: BLOAD "GBASIC",B0,P4864.
  47.  
  48. Once GBASIC is installed, the new keywords can be used just like any other
  49. BASIC commands.  You can even abbreviate them by shifting the second letter,
  50. as usual.  Remember that GBASIC must be active (not just resident) while you
  51. type in a program using its keywords, or they will not be tokenized
  52. correctly, and you will end up with a jungle of syntax errors.  Note also
  53. that GBASIC uses memory from 4864 to 7167 (only), so avoid POKEing around
  54. this area.
  55.  
  56. Hitting the beloved STOP/RESTORE combination will not deactivate GBASIC, but
  57. will turn off the interrupt-driven sprite shell.  Simple SYS 4864 again to
  58. bring it back when you need it.  The QUIT command (previously unimplemented
  59. on the 128) will shut off all facets of GBASIC, although SYS 4864 will bring
  60. it back to life.  Resetting the computer will also turn it off; however, due
  61. to its location, GBASIC will still be resident for later use as long as you
  62. haven't POKEd over its memory space.
  63.  
  64. GBASIC has been designed primarily for use with the 40-column screen, since
  65. sprites aren't supported in 80-column mode.  For this reason, very few of
  66. the commands will have any visible effect in 80 columns, and STORE, in
  67. particular, can have disastrous results to your screen presentation.
  68.  
  69. Now that we have the preamble out of the way, let's look at your new
  70. resources.  Certain conventions have been followed in this listing.  Sprite
  71. numbers are 1 to 8, as per BASIC 7.0.  Screen columns are numbered 0 to 39,
  72. and screen rows/lines are numbered 0 to 24 (unless, of course, a smaller
  73. window is in use).  In some cases, screen "zones" will be referred to: 0
  74. indicates normal screen memory, 1 indicates color memory.  Most parameters
  75. MUST be given for each command: those which are optional are noted in "< >"
  76.  
  77.  
  78. FUNCTIONS
  79. ---------
  80.  
  81. BANG(sprite)
  82.  
  83. Allows you to check for collisions between sprites and operates in a manner
  84. similar to BUMP (1).  However, the parameter specified is the number of the
  85. sprite in question, and the result will indicate only those collisions which
  86. affect that specific sprite.  For example, BANG(3) would check for
  87. collisions with sprite 3 ONLY and would return a 0 if none were occurring. 
  88. If sprite 3 was in contact with 5 and 7, this function would return 80 (16 +
  89. 64), even if other sprites were colliding on the screen.  Naturally, a
  90. sprite must be on to have a collision.  Note that this command is based on
  91. the position of the sprite and so may give unforgiving readings with sprite
  92. pictures that are much smaller than the actual possible sprite area.  For
  93. best results with small sprites, use the following formula:
  94.  
  95. B = BANG(x) AND BUMP(2)
  96.  
  97. This will only indicate a collision if the picture portion of the indicated
  98. sprite is touching another sprite, AND it will indicate exactly which
  99. sprites are involved in the tangle.
  100.  
  101. DICE(range)
  102.  
  103. Generates random numbers within a specified range of 2 to 128.  For example,
  104. D=DICE(6) would be the equivalent of rolling a six-sided dice and putting
  105. the result in D.  If the "range" parameter is 0 or 1, a new random seed is
  106. generated to begin a new sequence of random numbers - the equivalent of
  107. putting D=RND(-TI) at the beginning of your program.  It also generates a
  108. random number between 0 and 255.  Note that this command does not use the
  109. SID chip in any way, so you need not worry about tinkering with VOICE 3.
  110.  
  111.  
  112. COMMANDS
  113. --------
  114.  
  115. ANIMATE sprite, base, blocks, speed
  116.  
  117. This command animates the indicated sprite by shifting it through each shape
  118. in a sequence.  Since this action is controlled by the GBASIC interrupt, it
  119. will continue independent of program control.  The "base" is the first
  120. 64-byte block of the sequence, from 0 to 255: use 56 to start the sequence
  121. in the area reserved for sprites on the C-128 - memory location 3584.  The
  122. sprite will be shifted along the sequence a number of times indicated by
  123. "blocks" (1-255) before it returns to "base" and starts the sequence over
  124. again.  Thus, a "base" of 56 with 2 "blocks" would run 56, 57, 58, 56, 57...
  125.  ad infinitum.  "Speed" (0-255) controls how fast this animation occurs: low
  126. numbers are fast and high numbers are slow.  A "speed" of 5 to 8 generally
  127. works best.  Entering 0 for either "blocks" or "speed" will turn off the
  128. animation sequence for that sprite.  Entering ANIMATE by itself, with no
  129. parameters at all, will turn off animation for ALL sprites.
  130.  
  131. DEFAULT
  132.  
  133. This command allows you to quickly change the various sprite parameters
  134. without issuing several commands for each sprite.  It has the following
  135. effects:
  136.  
  137.  1) Sprite 1 is LINKed to joystick 2 with a speed of 2; all other LINKs are
  138. turned off.  This is the equivalent of issuing a LINK x,0,0,for every sprite
  139. except 1, and a LINK 1,2,2 for it.  See LINK.
  140.  
  141.  2) All sprites are FENCEd by the screen borders and will bounce off them
  142. without disappearing.  This is the equivalent of issuing a FENCa
  143. x,1,24,65,50,229 for every single sarite.  See FENCE.
  144.  
  145.  3) Animation is unaffected.
  146.  
  147. Essentially, this command is a quick way to set up the sprite parameters
  148. most commonly used in arcade games.
  149.  
  150. FENCE sprite, action, < x-left, x-right, y-top, y-bottom >
  151.  
  152. This command rides shotgun over your sprites, making sure that they stay
  153. within the boundaries you specify, regardless of MOVSPR and the like. 
  154. "Action" indicates what should happen when a sprite goes out of bounds:
  155.  
  156.  0 - Nothing (FENCE off)
  157.  1 - Stop
  158.  2 - Disappear (good for removing shots that go off-screen)
  159.  
  160. Note that a "stopped" sprite is only prevented from moving in the blocked
  161. direction (x or y).  If it is moving at an odd angle with both x and y
  162. vectors, it can still "crawl" along the border in the unblocked direction. 
  163. The "x-left", "x-right", "y-top" and "y-bottom" parameters specify the
  164. boundary zone.  For example, XL=24, XR=65, YT=50 and YB=229 would set the
  165. boundary exactly at the edges of the screen (the default value).  Note that
  166. the X-MSB is assumed for the right boundary, giving you the full width of
  167. the screen if you so desire it.
  168.  
  169. FILL zone, value
  170.  
  171. This command will fill either screen (zone 0) or color (zone 1) memory with
  172. the given "value" (0-255).  Note that only the current window is filled:
  173. this may or may not be the entire screen, depending on how you have
  174. specified any WINDOWs (BASIC 7.0) or FRAMEs (GBASIC).
  175.  
  176. FRAME top left column, top left row, bottom right column, bottom right row,
  177. frame character, frame color
  178.  
  179. Note: With the exception of the last two parameters, this syntax is as per
  180. the WINDOW command.
  181.  
  182. This command opens a cleared window anywhere on the screen, as per WINDOW. 
  183. However, it puts a frame around the window of the specified character
  184. (0-255) and color (0-15).  Note that the actual window size will be two less
  185. in width and length to accomodate the frame.  Parameters which do not allow
  186. for this will generate an ILLEGAL QUANTITY error.  This command can be
  187. combined with STORE and RECALL to create true "pop up" windows which
  188. disappear without a trace when closed.
  189.  
  190. HOME
  191.  
  192. Homes the cursor within the current window.
  193.  
  194. LCLEAR first line, last line
  195.  
  196. This command clears the indicated lines (0-24).  Naturally, the last line
  197. must be higher in value than the first.  Note that lines are only cleared
  198. within the boundaries of the current window, and the line values will be
  199. offset by the position of the window from the real top of the screen.
  200.  
  201. LINK sprite, port, speed
  202.  
  203. This command links the indicated "sprite" to the indicated joystick "port"
  204. (1-2), so that it moves in the appropriate direction when the stick is
  205. pushed.  The "speed" can also be changed from 1 (slow) to 16 (too fast for
  206. most purposes).  Entering 0 for "port" or "speed" will severe the LINK. 
  207. Since this routine is part of the sprite shell interrupt, it will operate
  208. independently from the BASIC program.  As with all sprite-moving commands,
  209. it is subject to FENCE limits, however.  Note that more than one sprite can
  210. be LINKed to the same stick to create giant-sized objects that move
  211. seamlessly together.
  212.  
  213. MCOPY bytes, from address, from bank, to address, to bank
  214.  
  215. This command copies chunks of memory from one location to another.  "Bytes"
  216. (1-65536) indicates the number of bytes to copy.  "Address" and "bank"
  217. ranges are as per usual, 0-65536 and 0-15 respectively.  Since it can move
  218. data from one bank to another, this command has many uses.  For example,
  219. MCOPY 2048,53248,14,14336,0 will almost instantly copy the character set to
  220. bank 0, address 14336, allowing you to alter it to suit your tastes.  POKE
  221. 2604,30 to see the new set.  As with all commands that alter memory
  222. directly, you should be VERY careful with MCOPY.
  223.  
  224. RECALL screen
  225.  
  226. This command allows you to RECALL a screen which has been previously STOREd.
  227. See below.
  228.  
  229. STORE screen
  230.  
  231. This command and its companion, RECALL, allow you to save and load full
  232. screens (including color) in memory.  You can have up to 8 screens, numbered
  233. 0 to 7, STOREd at a time.  The uses for these commands are infinite.  For
  234. example, you could STORE one or more "help windows" to be RECALLed as needed
  235. - also STOREing the current screen before the help window is called up so
  236. that it can be retrieved afterwards.  By preceding a FRAME or WINDOW command
  237. with STORE, you can RECALL the original screen later to create "pop up"
  238. windows which later vanish, leaving the first screen intact.  This
  239. versatility has one price: the screens are stored in 8563 RAM, making full
  240. use of the 80-column screen difficult, if not impossible, unless you stick
  241. to only screens 2 and 3, which cover normally unused 8563 RAM.  If this
  242. situation is intolerable, remember that MCOPY can also be used to save and
  243. load screens in other areas of memory.
  244.  
  245. TRANS from zone, from value, to zone, to value
  246.  
  247. TRANS (short for "TRANSMUTE") scans the entire screen and alters only the
  248. portions of it which you specify.  It will look through either screen or
  249. color memory (zone 0 or 1) for every occurrence of the noted "from value"
  250. (0-255), and then alter it, in the appropriate "to zone" (0-1), to the new
  251. "to value" (0-255).  A few examples will make this more clear.  Remembering
  252. that the screen codes 1 and 2 are "A" and "B" respectively, and the color
  253. codes 3 and 4 are cyan and purple respectively:
  254.  
  255.  TRANS 0,1,0,2: Change every "A" on the screen to a "B"
  256.  TRANS 1,3,1,4: Paint every cyan character on the screen purple.
  257.  TRANS 0,1,1,4: Paint every "A" on the screen purple.
  258.  TRANS 1,3,0,2: Change every cyan character on the screen to a "B"
  259.  
  260. Obviously, this command is of particular use in creating interesting
  261. animation effects.
  262.  
  263. QUIT
  264.  
  265. This command simply turns off GBASIC.  SYS 4864 to reactivate it.
  266.  
  267. MINE
  268.  
  269. This is perhaps the most unusual command of all and is aimed mainly at
  270. machine language programmers.  Normally, issuing MINE will give an
  271. UNIMPLEMENTED COMMAND error.  However, by POKEing an address into memory
  272. locations 7166-7167 (low byte/high byte format), you will cause the MINE
  273. command to execute a machine language routine of your creation at this
  274. location.  A good place to put this routine is in the mostly unused area
  275. from $B00 to $BFF, since it is in common RAM and will allow you to avoid
  276. banking hassles.  "POKE 7166,0: POKE 7167,11" will set this up.  The demo
  277. program (see below) uses a short routine of this sort to place the comet and
  278. get it moving at the chosen speed.
  279.  
  280. For really large routines, you can use the area from 7168 to 16383(!), but
  281. this will necessitate setting up the graphic area without actually using it
  282. (GRAPHIC1: GRAPHIC0).  This has the advantage that you can then BSAVE a new
  283. version of GBASIC with your routine permanently added on.  BSAVE "GBASIC",
  284. B0, P4864 TO P(x+1), where "x" is the end address of your routine, will
  285. accomplish this.
  286.  
  287. If you would like the MINE command to take in parameters, the following
  288. coding will usually do the trick:
  289.  
  290.  JSR $0386
  291.  JSR $AF96
  292.  JSR $AF0C
  293.  
  294. Place this in your code to retrieve each parameter.  It will return the low
  295. byte in the Y-Register and the high byte in the Accumulator (i.e.  "MINE
  296. 1026" would return 2 in YREG and 4 in ACC).  Commas are automatically dealt
  297. with by the built-in routines.  If you want to save some space, the second
  298. two commands are built into a subroutine in GBASIC itself at $1697, i.e. 
  299. the three can be replaced with: JSR $0386 : JSR $1697.  If you want to limit
  300. input to one byte (numbers from 0-255), there is also a built-in routine for
  301. this: JSR $0386 : JSR $16A0.  Single byte parameters will show up in YREG;
  302. multi-byte inputs (256+) will generate an ILLEGAL QUANTITY error.
  303.  
  304. I have included a demo program to get you used to the capabilities of the
  305. new commands.  Of course, it is more of a game portion than a full program,
  306. but it will give you some idea of what you can now accomplish.  In
  307. particular, you should list the program and study how each command is used. 
  308. See if you can find the game's main loop: you may be amazed at how short it
  309. is, since virtually all movement is controlled with the GBASIC and C-128
  310. interrupts.
  311.  
  312. There is one final trick that you might find handy to have in your arsenal. 
  313. As previously noted the GBASIC module must naturally be active to run a
  314. program using its commands.  With a little careful coding, you can link it
  315. permanently to your program so that the two files LOAD and SAVE together -
  316. in effect, a GBASIC runtime module.  Here's how to do it:
  317.  
  318.  1) Design your program using the GBASIC commands as usual.  Don't bother
  319. having it BLOAD GBASIC - this won't be necessary once they are linked
  320. together.  Just make sure that the first line has SYS 4864.
  321.  
  322.  2) When you are happy with the results, make sure that both GBASIC and your
  323. program are in memory.  Be certain that your program is in the normal area
  324. reserved for BASIC and not pushed up above the graphics area.  A GRAPHICCLR
  325. command will do this.
  326.  
  327.  3) In direct mode, lower the start of BASIC by entering the following:
  328.  
  329. POKE45,0:POKE46,19
  330.  
  331. then DSAVE your program normally.  Don't forget to push BASIC back to its
  332. normal location afterwards with:
  333.  
  334. POKE45,1:POKE46,28
  335.  
  336. If you study the block count of your program, you'll notice that it is now
  337. longer: the GBASIC module is attached to it.
  338.  
  339. There are only two catches to this trick:
  340.  
  341.  1) Your program will not work properly if the graphics area is in use when
  342. it is first loaded, since GBASIC will end up in the wrong place.  It WILL
  343. work all right if the graphics area is set up afterwards, however.
  344.  
  345.  2) You must use the LOAD "filename",8,1 syntax to LOAD the program from now
  346. on.  DLOAD will assume that GBASIC is a normal BASIC program itself and
  347. place it in the wrong area, with your program crammed on top.
  348.  
  349. That's about all there is to it.  Once you get the syntax down, the commands
  350. are very easy to use and will perform many tasks in the background that you
  351. would normally have to code yourself.  Now you can create that epic arcader
  352. you've been dreaming about, and maybe even get it published on LOADSTAR!
  353.  
  354. JM
  355.                              **** End of Text ****
  356.